// Copyright(c) Sonosemi Medical Ltd. Embedded Software Team.
// Author: Zhang Yisong(zhangyisong@sonosemi.com)

#pragma once

#include <cstddef>
#include <type_traits>

namespace active {

template <size_t> struct QueueSize;
template <size_t> struct Priority;
namespace internal {

template <typename T> struct is_queuesize : public std::false_type {};
template <typename T> struct is_priority : public std::false_type {};
template <typename T> struct is_task_config : public std::false_type {};

template <size_t size = 0, size_t prio = 0> struct TaskConfig {
  static constexpr auto kQueueSize = size;
  static constexpr auto kPriority = prio;
};

template <size_t size, size_t prio>
struct is_task_config<TaskConfig<size, prio>> : public std::true_type {};
template <size_t size>
struct is_queuesize<QueueSize<size>> : public std::true_type {};
template <size_t size>
struct is_priority<Priority<size>> : public std::true_type {};
} // namespace internal

namespace concepts {
template <typename T>
concept TaskConfigable = internal::is_task_config<T>::value;
template <typename T>
concept QueueSizable = internal::is_queuesize<T>::value;
template <typename T>
concept Priotible = internal::is_priority<T>::value;

template <typename T>
concept QueueItemable =
    internal::is_queuesize<T>::value or internal::is_priority<T>::value;
} // namespace concepts

} // namespace active